/*******************************************************************************
 * 用于定义全局使用的变量,工具方法 version 1.0 2010-11-13 ahthor yewl
 ******************************************************************************/
var common = {};
common.base = {};

/**
 * 判断一个值是否为空 为null(undefined)或空字符串返回true 空数组也返回true
 */
function isNull(v) {
	if (v == null || v == "") {
		return true;
	}
	if (v instanceof Array) {
		if (v.length == 0) {
			return true;
		}
	}
	return false;
}

/**
 * 判断一个值是否为数字，并提示
 */
function isNumber(v) {
	if (isNaN(v)) {
		return false;
	}
	return true;
}

/**
 * 打开一个出口 href:连接地址；width:宽度，百分比；height：高度，百分比
 */
function win(href, width, height) {
	if (isNull(width)) {
		width = 0.5;
	}
	if (isNull(height)) {
		height = 0.5;
	}
	var w = screen.width * width;
	var h = screen.availHeight * height;
	var x = (screen.width - w) / 2;
	var y = (screen.availHeight - h) / 2;
	window
			.open(
					href,
					"_blank",
					"toolbar=no,location=no,status=yes,menubar=no,scrollbars=yes,resizable=yes,left="
							+ x + ",top=" + y + ",width=" + w + ",height=" + h);
}

/**
 * 打开一个dialog
 * 
 * @param url
 * @param param
 *            参数
 * @param w
 *            长度 单位：px
 * @param h
 *            高度 单位：px
 * @return
 */
function openDialog(url, param, w, h) {
	if (isNull(param)) {
		param = "default";
	}
	if (isNull(w)) {
		w = 500;
	}
	if (isNull(h)) {
		h = 510
	}
	if (isNull(feature)) {
		feature = "dialogWidth=500px;dialogHeight=510px;scroll:yes;help:no";
	}
	var feature = "dialogWidth=" + w + "px;dialogHeight=" + h
			+ "px;scroll:yes;help:no";
	var rv = window.showModalDialog(url, param, feature);
	if (isNull(rv)) {
		rv = "";
	}
	return rv;
}

/**
 * base64加密
 * 
 * @param input
 * @return
 */
common.base.Base64 = function() {
	// private property
	_keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

	// public method for encoding
	this.encode = function(input) {
		var output = "";
		var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
		var i = 0;
		input = _utf8_encode(input);
		while (i < input.length) {
			chr1 = input.charCodeAt(i++);
			chr2 = input.charCodeAt(i++);
			chr3 = input.charCodeAt(i++);
			enc1 = chr1 >> 2;
			enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
			enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
			enc4 = chr3 & 63;
			if (isNaN(chr2)) {
				enc3 = enc4 = 64;
			} else if (isNaN(chr3)) {
				enc4 = 64;
			}
			output = output + _keyStr.charAt(enc1) + _keyStr.charAt(enc2)
					+ _keyStr.charAt(enc3) + _keyStr.charAt(enc4);
		}
		return output;
	}

	// public method for decoding
	this.decode = function(input) {
		var output = "";
		var chr1, chr2, chr3;
		var enc1, enc2, enc3, enc4;
		var i = 0;
		input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
		while (i < input.length) {
			enc1 = _keyStr.indexOf(input.charAt(i++));
			enc2 = _keyStr.indexOf(input.charAt(i++));
			enc3 = _keyStr.indexOf(input.charAt(i++));
			enc4 = _keyStr.indexOf(input.charAt(i++));
			chr1 = (enc1 << 2) | (enc2 >> 4);
			chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
			chr3 = ((enc3 & 3) << 6) | enc4;
			output = output + String.fromCharCode(chr1);
			if (enc3 != 64) {
				output = output + String.fromCharCode(chr2);
			}
			if (enc4 != 64) {
				output = output + String.fromCharCode(chr3);
			}
		}
		output = _utf8_decode(output);
		return output;
	}

	// private method for UTF-8 encoding
	_utf8_encode = function(string) {
		string = string.replace(/\r\n/g, "\n");
		var utftext = "";
		for (var n = 0; n < string.length; n++) {
			var c = string.charCodeAt(n);
			if (c < 128) {
				utftext += String.fromCharCode(c);
			} else if ((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			} else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}

		}
		return utftext;
	}

	// private method for UTF-8 decoding
	_utf8_decode = function(utftext) {
		var string = "";
		var i = 0;
		var c = c1 = c2 = 0;
		while (i < utftext.length) {
			c = utftext.charCodeAt(i);
			if (c < 128) {
				string += String.fromCharCode(c);
				i++;
			} else if ((c > 191) && (c < 224)) {
				c2 = utftext.charCodeAt(i + 1);
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			} else {
				c2 = utftext.charCodeAt(i + 1);
				c3 = utftext.charCodeAt(i + 2);
				string += String.fromCharCode(((c & 15) << 12)
						| ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}
		}
		return string;
	}
}

// 错误信息打印
window.onerror = function(a, b, c) {
	try {
		var errorHtml = [];
		errorHtml.push("<PRE style='font-size:12px;'>");
		errorHtml.push("<FONT color=blue>时间: </FONT><FONT color=red>"
				+ new Date().toLocaleString() + "</FONT>");
		errorHtml.push("<BR/>");
		errorHtml.push("<FONT color=blue>错误: </FONT>");
		errorHtml.push(a);
		errorHtml.push("<BR/>");
		errorHtml.push("<FONT color=blue>文件: </FONT>");
		errorHtml.push(b);
		errorHtml.push("<BR/>");
		errorHtml.push("<FONT color=blue>行号: </FONT>")
		errorHtml.push(c);
		errorHtml.push("<BR/>");
		errorHtml.push("<BR/>");
		errorHtml.push("<FONT color=blue>堆栈: </FONT>")
		errorHtml.push("<BR/>");
		var callFun = arguments.callee.caller; // /window.onerror.caller;
		for (; callFun;) {
			var args = [];
			for (var i = 0; i < callFun.arguments.length; i = i + 1) {
				args.push(callFun.arguments[i]);
			}
			errorHtml.push("<FONT color='#887788'>参数: </FONT>")
			errorHtml.push(args.toString());
			errorHtml.push("<BR/>");
			errorHtml.push(("" + callFun).replace(/</g, "&lt;").replace(/>/g,
					"&gt;"));
			errorHtml.push("<BR/><HR/>");
			callFun = callFun.caller;
		}
		errorHtml.push("</PRE>");
		var errorInfo = window.open("", "errorInfo", "");
		errorInfo.document.write(errorHtml.join(""));
	} catch (e) {
	}
}

// 关闭窗口
function closeWindow() {
	if (window == top) {
		try {
			if (window.opener && window.opener.refresh) {
				window.opener.refresh();
			}
			window.opener = null;
		} catch (e) {
		}
		window.close();
	} else {
		try {
			window.setInterval(window.history.back, 300);
		} catch (e) {
		}
	}
}

// 获取页面URL参数
function request(paras) {
	var url = location.href;
	var paraString = url.substring(url.indexOf("?") + 1, url.length).split("&");
	var paraObj = {}
	for (i = 0; j = paraString[i]; i++) {
		paraObj[j.substring(0, j.indexOf("=")).toLowerCase()] = j.substring(j
				.indexOf("=") + 1, j.length);
	}
	var returnValue = paraObj[paras.toLowerCase()];
	if (typeof (returnValue) == "undefined") {
		return "";
	} else {
		return returnValue;
	}
}

// 字符串转日期
function strToDate(str) {
	str = str.replace(/-/g, "/");
	return new Date(str);
}

// 日期转字符串
function dateToStr(date) {
	var yy = date.getFullYear(); // 年
	var mm = date.getMonth() + 1; // 月
	var dd = date.getDate(); // 日
	var clock = yy + "-";
	if (mm < 10)
		clock += "0";
	clock += mm + "-";
	if (dd < 10)
		clock += "0";
	clock += dd + " ";
	return clock;
}

/*
 * 固定电话号码格式 因为固定电话格式比较复杂，情况比较多，主要验证了以下类型
 * 如：010-12345678、0912-1234567、(010)-12345678、(0912)1234567、(010)12345678、(0912)-1234567、01012345678、09121234567
 */
var regPhone = /^(^0\d{2}-?\d{8}$)|(^0\d{3}-?\d{7}$)|(^0\d2-?\d{8}$)|(^0\d3-?\d{7}$)$/;

/*
 * Email邮箱 如：zhangsan@163.com、li-si@236.net、wan_gwu999@SEED.NET.TW
 */
var regEmail = /^([a-zA-Z0-9]+[_|\-|\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\-|\.]?)*[a-zA-Z0-9]+(\.[a-zA-Z]{2,3})+$/;

/*
 * 身份证15位编码规则：dddddd yymmdd xx p dddddd：6位地区编码 yymmdd: 出生年(两位年)月日，如：910215 xx:
 * 顺序编码，系统产生，无法确定 p: 性别，奇数为男，偶数为女
 * 
 * 身份证18位编码规则：dddddd yyyymmdd xxx y dddddd：6位地区编码 yyyymmdd:
 * 出生年(四位年)月日，如：19910215 xxx：顺序编码，系统产生，无法确定，奇数为男，偶数为女 y: 校验码，该位数值可通过前17位计算获得
 * 
 * 前17位号码加权因子为 Wi = [ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 ] 验证位
 * Y = [ 1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2 ] 如果验证码恰好是10，为了保证身份证是十八位，那么第十八位将用X来代替
 * 校验位计算公式：Y_P = mod( ∑(Ai×Wi),11 ) i为身份证号码1...17 位; Y_P为校验码Y所在校验码数组位置
 */
function validateIdCard(idCard) {
	var flag = false;
	// 15位和18位身份证号码的正则表达式
	var regIdCard = /^(^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$)|(^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[Xx])$)$/;

	// 如果通过该验证，说明身份证格式正确，但准确性还需计算
	if (regIdCard.test(idCard)) {
		if (idCard.length == 18) {
			var idCardWi = new Array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10,
					5, 8, 4, 2); // 将前17位加权因子保存在数组里
			var idCardY = new Array(1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2); // 这是除以11后，可能产生的11位余数、验证码，也保存成数组
			var idCardWiSum = 0; // 用来保存前17位各自乖以加权因子后的总和
			for (var i = 0; i < 17; i++) {
				idCardWiSum += idCard.substring(i, i + 1) * idCardWi[i];
			}

			var idCardMod = idCardWiSum % 11;// 计算出校验码所在数组的位置
			var idCardLast = idCard.substring(17);// 得到最后一位身份证号码

			// 如果等于2，则说明校验码是10，身份证号码最后一位应该是X
			if (idCardMod == 2) {
				if (idCardLast == "X" || idCardLast == "x") {
					flag = true;
				}
			} else {
				// 用计算出的验证码与最后一位身份证号码匹配，如果一致，说明通过，否则是无效的身份证号码
				if (idCardLast == idCardY[idCardMod]) {
					flag = true;
				}
			}
		}
	}
	return flag;
}

/*
 * 只能为正整数
 */
var regNum = /^\d+$/;

/*
 * 邮政编码
 */
var regPostCode = /^\d{6}$/;

/*
 * 用户名 只能是字母数字下划线，并且以字母开头(5-16位)
 */
var regUserName = /^[a-zA-Z]\w{4,15}$/;

/*
 * IP地址 如：192.168.1.102
 */
var regIP = /^((([1-9]\d?)|(1\d{2})|(2[0-4]\d)|(25[0-5]))\.){3}(([1-9]\d?)|(1\d{2})|(2[0-4]\d)|(25[0-5]))$/;

/*
 * 只能是中文汉字
 */
var regChineseChar = /^[\u4e00-\u9fa5]+$/;

/*
 * 网址 只允许http、https、ftp这三种 如：http://www.baidu.com
 */
var regWeb = /^(([hH][tT]{2}[pP][sS]?)|([fF][tT][pP]))\:\/\/[wW]{3}\.[\w-]+\.\w{2,4}(\/.*)?$/;

/*
 * 日期格式验证 因为日期格式比较多，主要验证了以下类型 2012-05-14、2012/05/6、2012.5.14、20120528
 */
var regDate = /^[1-9]\d{3}([-|\/|\.])?((0\d)|([1-9])|(1[0-2]))\1(([0|1|2]\d)|([1-9])|3[0-1])$/;

/*
 * 调用以上正则表达式的方法 以验证电话号码格式为例
 */
function onCheckTel(tel) {
	var regMobile = /^1[1,2,3,4,5,6,7,8,9]\d{9}$/;
	var flag = false;
	if (regMobile.test(tel)) {
		flag = true;
	}
	return flag;
}


